package app

import (
	"log"

	"github.com/gin-gonic/gin"

	"github.com/Kindling-project/chaos-backend/configs"
	"github.com/Kindling-project/chaos-backend/internal/manager"
	"github.com/Kindling-project/chaos-backend/internal/service"
	"github.com/Kindling-project/chaos-backend/tools/graphql"
	"github.com/Kindling-project/chaos-backend/tools/kubernetescli"
	pqlCli "github.com/Kindling-project/chaos-backend/tools/prometheuscli"
)

var DefaultEngine *gin.Engine

func SetupApplication(
	authType configs.AuthType,
	kubeConfigPath string,
	skywalkingUIAddr string,
	prometheusUIAddr string,
	trainTicketUIAddr string,
	chaosTemplateFilePath string,
	unstructuredChaosFilePath string,
	metricSource string,
	enableDebug bool,
) *gin.Engine {

	if enableDebug {
		gin.SetMode(gin.DebugMode)
	} else {
		gin.SetMode(gin.ReleaseMode)
	}

	DefaultEngine = gin.Default()
	cfg := configs.Config{
		KubeAPIConfig: configs.APIConfig{
			AuthType:     authType,
			AuthFilePath: kubeConfigPath,
		},
		ChaosTemplateFilePath:     chaosTemplateFilePath,
		UnstructuredChaosFilePath: unstructuredChaosFilePath,
		SkywalkingUIAddr:          skywalkingUIAddr,
		PrometheusUIAddr:          prometheusUIAddr,
		TrainTicketUIAddr:         trainTicketUIAddr,
		MetricSource:              metricSource,
	}

	DefaultEngine.Use(Cors())
	SetupRouter(DefaultEngine)
	SetupKubeAuthConfig(cfg)
	SetupThirdPartyDataSource(cfg)
	SetupTrainTicketAddr(cfg)
	SetupChaosTemplate(cfg)

	// TODO logger
	return DefaultEngine
}

func SetupKubeAuthConfig(cfg configs.Config) {
	restConfig, err := configs.CreateRestConfig(cfg.KubeAPIConfig)
	if err != nil {
		panic(err)
	}
	err = kubernetescli.SetupConfig(restConfig)
	if err != nil {
		panic(err)
	}
}

func SetupChaosTemplate(cfg configs.Config) {
	manager.SetupChaosTemplate(cfg.ChaosTemplateFilePath)
	err := kubernetescli.SetupChaosTemplate(cfg.UnstructuredChaosFilePath)
	if err != nil {
		log.Panicf("failed to read unstructured chaos template: %v", err)
	}
}

func SetupThirdPartyDataSource(cfg configs.Config) {
	graphql.SetupSkywalkingUIAddr(cfg.SkywalkingUIAddr)

	err := pqlCli.SetupMetricAPI(cfg.PrometheusUIAddr)
	if err != nil {
		log.Printf("Prometheus client init failed, %s", err)
	}

	service.SetDatasource(cfg.MetricSource)
}

func SetupTrainTicketAddr(cfg configs.Config) {
	service.SetupTrainTicketAddr(cfg.TrainTicketUIAddr)
}
